package top.hekun.study.core.util;


import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 〈ASM工具类示例〉
 *
 * @author: Sakura
 * @date: 2023/4/24
 */
public class AsmToolDemo {
    // 读取class文件 输出为ASM代码
    public static void main(String[] args) throws IOException {
        // 设置参数 或者直接给 ClassReader 传类的全名称
        byte[] classBytes = ClassFileUtil.getClassFileByteToClassName("HelloWord");
        // 分析选项  SKIP_CODE 跳过代码码  SKIP_DEBUG  跳过测试  SKIP_FRAMES 跳过帧  EXPAND_FRAMES 展开框架  可组合使用 也可以是 0
        int parsingOptions = ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG;
        // true 打印asm代码  ;false 打印class 方法对应的 指令
        boolean asmCode = true;
        // 打印结果
        // 设置打印工具
        Printer printer = asmCode ? new ASMifier() : new Textifier();
        File classFileModelPath = ClassFileUtil.getClassFileModelPath();
        String className = "HelloWordDump";
        File file = new File(ClassFileUtil.getClassFileModelPath(), className + ".java");
        FileOutputStream outputStream = new FileOutputStream(file, false);
        // 打印编写器
        PrintWriter printWriter = new PrintWriter(outputStream, true);
        // 追踪类工具
        TraceClassVisitor traceClassVisitor = new TraceClassVisitor(null, printer, printWriter);
        // 类读取器 并且解析
        new ClassReader(classBytes)
                .accept(traceClassVisitor, parsingOptions);

        outputStream.close();
    }

    /**
     * 另外一种调用方法
     * 可以以在命令行 直接调用ASMifier.main() 方好 直接执行
     *
     * @throws IOException
     */
    private void PrinterMainDemo() throws IOException {
        String[] args = new String[]{"-debug", "top.hekun.study.core.model.HelloWord"};
        ASMifier.main(args);
        Textifier.main(args);
    }

}
